package 每日一题;

import java.util.ArrayDeque;
import java.util.Deque;

public class No581最短无序连续子数组 {

    /**
     * 给你一个整数数组 nums ，你需要找出一个 连续子数组 ，
     * 如果对这个子数组进行升序排序，那么整个数组都会变为升序排序。
     * 请你找出符合题意的 最短 子数组，并输出它的长度。
     *
     * 示例 1：
     * 输入：nums = [2,6,4,8,10,9,15]
     * 输出：5
     * 解释：你只需要对 [6, 4, 8, 10, 9] 进行升序排序，那么整个表都会变为升序排序。
     * 示例 2：
     * 输入：nums = [1,2,3,4]
     * 输出：0
     * 示例 3：
     * 输入：nums = [1]
     * 输出：0
     *  
     * 提示：
     * 1 <= nums.length <= 104
     * -105 <= nums[i] <= 105
     *
     * 进阶：你可以设计一个时间复杂度为 O(n) 的解决方案吗？
     */

    public int findUnsortedSubarray(int[] nums) {
        /**
         * 1.双重遍历找到无序的最左边和最右边
         * 2.利用栈
         * 3.快排后,再遍历数组原地比对
         */
        return method1(nums);
    }

    private int method2(int[] nums) {

        if(nums.length<2){
            return 0;
        }

        Deque<Integer> stack=new ArrayDeque<>();
        int left=nums.length-1;
        for (int i = 0; i < nums.length; i++) {
            while (!stack.isEmpty()&&nums[stack.peekLast()]>nums[i]){
                left=Math.min(left,stack.pollLast());
            }
            stack.addLast(i);
        }

        if(left==nums.length-1){
            return 0;
        }

        stack.clear();
        int right=0;
        for (int i = nums.length-1; i >= 0; i--) {
            while (!stack.isEmpty()&&nums[stack.peekLast()]<nums[i]){
                right=Math.max(right,stack.pollLast());
            }
            stack.addLast(i);
        }

        if(right==0){
            return 0;
        }

        return right-left+1;
    }

    //最坏 n^2情况
    private int method1(int[] nums){

        if(nums.length<2){
            return 0;
        }

        int left=nums.length-1;
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j < nums.length; j++) {
                if(nums[i]>nums[j]){
                    left=Math.min(left,i);
                    break;
                }
            }
            if(left!=nums.length-1){
                break;
            }
        }

        int right=0;
        for (int i = nums.length-1; i >= 0; i--) {
            for (int j = i-1; j >= 0; j--) {
                if(nums[j]>nums[i]){
                    right=Math.max(right,i);
                    break;
                }
            }
            if(right!=0){
                break;
            }
        }

        return right-left+1<0?0:right-left+1;
    }

    public static void main(String[] args) {
        No581最短无序连续子数组 n=new No581最短无序连续子数组();
        int[] arr={1,2,3,4};
        int result1 = n.method1(arr);
        int result2 = n.method2(arr);
        System.out.println(result1);
        System.out.println(result2);
    }



}
